package ViewsTUI;

import Controllers.*;
import Models.*;
import byggemarked.*;
import java.util.ArrayList;
import java.util.Date;

/**
 * @author Morten
 */
public class RentalView
{
    private RentalCTR controller;

    public RentalView()
    {
        this.controller = new RentalCTR();
        ArrayList<String> options = new ArrayList<String>();
		options.add("Tilføj udlejning");
		options.add("Find udlejning");
		options.add("Hent udlejning");
		options.add("Redigér udlejning");
		options.add("Aflever udlejning");


		boolean isTimeToQuit = false;
		while(!isTimeToQuit)
		{
			Console.printMenu(true, "-Udlejning-", options);
			int choice = Console.readChoice(0,4);
			switch(choice)
			{
				case 1: addRental();    break;
				case 2: findRental();   break;
				case 3: getRental();	break;
				case 4: editRental();   break;
				case 5: returnRental(); break;
            	case 0: isTimeToQuit = true;
			}
		}
    }

    private void addRental()
    {
		MachineCTR machines = new MachineCTR();
		Console.print("Indtast ID på den ønskede maskine:");
		Machine machine = null;
		boolean hasValidValue = false;
		while(!hasValidValue)
		{
			int machineInt = Console.readInt();
			machine = machines.getMachine(machineInt);
			if(machine != null)
			{
				hasValidValue = true;
			}
			else
			{
				Console.print("Der findes ingen maskine med det valgte ID. Prøv igen.");
			}
		}

		CustomerCTR customers = new CustomerCTR();
		Console.print("Indtast ID på den ønskede kunde:");
		Customer customer = null;
		hasValidValue = false;
		while(!hasValidValue)
		{
			int customerInt = Console.readInt();
			customer = customers.getCustomer(customerInt);
			if(customer != null)
			{
				hasValidValue = true;
			}
			else
			{
				Console.print("Der findes ingen kunde med det valgte ID. Prøv igen.");
			}
		}

		Console.print("Indtast depositum:");
		double deposit = Console.readDouble();

		Console.print("Indtast pris pr dag:");
		double pricePerDay = Console.readDouble();

		this.controller.addRental(machine, customer, deposit, pricePerDay);
    }

    private void findRental(boolean standAlone)
    {
		Console.print("Indtast udlejningsdato (DD-MM-YYYY):");
		Date rentalDate = Console.readDate(true);

		Console.print("Indtast forventet afleveringsdato (DD-MM-YYYY):");
		Date expectedReturnDate = Console.readDate(true);

		Console.print("Indtast afleveringsdato (DD-MM-YYYY):");
		Date returnDate = Console.readDate(true);

		MachineCTR machines = new MachineCTR();
		Console.print("Indtast ID på den ønskede maskine:");
		Machine machine = null;
		boolean hasValidValue = false;
		while(!hasValidValue)
		{
			int machineInt = Console.readInt(true);
			if(machineInt != 99)
			{
				machine = machines.getMachine(machineInt);
				if(machine != null)
				{
					hasValidValue = true;
				}
				else
				{
					Console.print("Der findes ingen maskine med det valgte ID. Prøv igen.");
				}
			}
			else
			{
				machine = null;
				hasValidValue = true;
			}
		}

		CustomerCTR customers = new CustomerCTR();
		Console.print("Indtast ID på den ønskede kunde:");
		Customer customer = null;
		hasValidValue = false;
		while(!hasValidValue)
		{
			int customerInt = Console.readInt(true);
			if(customerInt != 99)
			{
				customer = customers.getCustomer(customerInt);
				if(customer != null)
				{
					hasValidValue = true;
				}
				else
				{
					Console.print("Der findes ingen kunde med det valgte ID. Prøv igen.");
				}
			}
			else
			{
				customer = null;
				hasValidValue = true;
			}
		}

		Console.print("Indtast depositum:");
		double deposit = Console.readDouble(true);

		Console.print("Indtast pris pr dag:");
		double pricePerDay = Console.readDouble(true);

		Console.print("Indtast den totale pris:");
		double totalPrice = Console.readDouble(true);

        ArrayList<Rental> rentals = this.controller.findRental(rentalDate, expectedReturnDate, returnDate, machine, customer, deposit, pricePerDay, totalPrice);
        if(rentals.size() > 0)
		{
			this.showList(rentals);
			if(standAlone)
			{
				Console.print("Indtast den ønskede udlejnings ID, som står ude til venstre i listen.");
				int id = Console.readInt();
				Rental rental = this.controller.getRental(id);
				if(rental != null)
				{
					this.showInfo(rental);
				}
				else
				{
					Console.print("Der kunne ikke findes nogen udlejning med det valgte ID.");
				}
			}
		}
		else
		{
			Console.print("Der fandtes ingen udlejninger med de indtastede søgekriterier.");
		}
    }

	private void findRental()
	{
		this.findRental(true);
	}

	private void getRental()
	{
		Console.print("Indtast udlejningens ID.");
		int rentalInt = Console.readInt();
		Rental rental = this.controller.getRental(rentalInt);
		if(rental != null)
		{
			showInfo(rental);
		}
		else
		{
			Console.print("Der kunne ikke findes nogen udlejning med det valgte ID.");
		}
	}
	
	private void editRental()
    {
		Console.print("For at redigere en udlejning, skal den først findes.");
        Rental rental = null;
        boolean hasValidRental = false;
        while(!hasValidRental)
        {
            try
			{
				rental = searchProcedure();
				if(rental != null)
				{
					hasValidRental = true;
				}
				else
				{
					return;
				}
			}
			catch(Exception e)
			{ }
        }
        Console.print("Du får nu muligheden for at redigere de enkelte felter seperat. Hvis et felt ikke ønskes ændret, springes feltet over med ENTER. Den nuværende værdi i feltet vises i parantes i linien ovenover.");
		Console.print("Indtast udlejningsdato (DD-MM-YYYY):");
		Date rentalDate = Console.readDate(true);
		if(rentalDate != null) { rental.setRentalDate(rentalDate); }

		Console.print("Indtast forventet afleveringsdato (DD-MM-YYYY):");
		Date expectedReturnDate = Console.readDate(true);
		if(expectedReturnDate != null) { rental.setExpectedReturnDate(expectedReturnDate); }

		Console.print("Indtast afleveringsdato (DD-MM-YYYY):");
		Date returnDate = Console.readDate(true);
		if(returnDate != null) { rental.setReturnDate(returnDate); }

		MachineCTR machines = new MachineCTR();
		Console.print("Indtast ID på den ønskede maskine:");
		Machine machine = null;
		boolean hasValidValue = false;
		while(!hasValidValue)
		{
			int machineInt = Console.readInt(true);
			if(machineInt != 0)
			{
				machine = machines.getMachine(machineInt);
				if(machine != null)
				{
					hasValidValue = true;
				}
				else
				{
					Console.print("Der findes ingen maskine med det valgte ID. Prøv igen.");
				}
			}
			else
			{
				machine = null;
				hasValidValue = true;
			}
		}
		if(machine != null) { rental.setMachine(machine); }

		CustomerCTR customers = new CustomerCTR();
		Console.print("Indtast ID på den ønskede kunde:");
		Customer customer = null;
		hasValidValue = false;
		while(!hasValidValue)
		{
			int customerInt = Console.readInt();
			if(customerInt != 0)
			{
				customer = customers.getCustomer(customerInt);
				if(customer != null)
				{
					hasValidValue = true;
				}
				else
				{
					Console.print("Der findes ingen kunde med det valgte ID. Prøv igen.");
				}
			}
			else
			{
				customer = null;
				hasValidValue = true;
			}
		}
		if(customer != null) { rental.setCustomer(customer); }

		Console.print("Indtast depositum:");
		double deposit = Console.readDouble();
		if(deposit != 0) { rental.setDeposit(deposit); }

		Console.print("Indtast pris pr dag:");
		double pricePerDay = Console.readDouble();
		if(pricePerDay != 0) { rental.setPricePerDay(pricePerDay); }

		Console.print("Indtast den totale pris:");
		double totalPrice = Console.readDouble();
		if(totalPrice != 0) { rental.setTotalPrice(totalPrice); }
    }

	private void returnRental()
    {
        Console.print("For at aflevere en udlejning, skal den først findes.");
		Rental rental = null;
		boolean hasValidRental = false;
		while(!hasValidRental)
		{
			try
			{
				rental = searchProcedure();
				if(rental != null)
				{
					hasValidRental = true;
				}
				else
				{
					return;
				}
			}
			catch(Exception e)
			{ }
		}
		this.controller.returnRental(rental);
		Console.print("Udlejningen med ID: "+rental.getId()+" er nu afleveret.");
    }

	private Rental searchProcedure() throws Exception
	{
		Console.print("Hvordan vil du finde udlejningen?");
		ArrayList<String> options = new ArrayList<String>();
		options.add("ID");
		options.add("Søgning");
		options.add("Liste");
		Console.printMenu(false, null, options);

		int choice = Console.readChoice(0, 3);
		int id = 0;
		boolean doSomething = true;
		switch(choice)
		{
			case 1:
				Console.print("Indtast udlejningens ID.");
				id = Console.readInt();
				break;
			case 2:
				Console.print("Indtast den ønskede udlejnings ID, som står ude til venstre i listen af søgeresultater.");
				this.findRental(false);
				id = Console.readInt();
				break;
			case 3:
				Console.print("Indtast den ønskede udlejnings ID, som står ude til venstre i listen.");
				this.showList(this.controller.getAllRentals());
				id = Console.readInt();
				break;
			case 99:
			case 0:
				doSomething = false;
				break;

		}
		if(doSomething)
		{
			Rental rental = this.controller.getRental(id);
			if(rental != null)
			{
				return rental;
			}
			else
			{
				Console.print("Der kunne ikke findes nogen udlejninger med det valgte ID.");
				throw new Exception();
			}
		}
		else
		{
			return null;
		}
	}

	private int showList(ArrayList<Rental> rentals)
	{
		int i = 0;
        for (Rental rental : rentals)
        {
			i++;
			Console.print("{"+rental.getId()+"} "+rental.getMachine().getName()+"\t"+rental.getCustomer().getId());
        }
		return i;
	}

	private void showInfo(Rental rental)
	{
		String name;
		if(rental.getCustomer() instanceof PrivateCustomer)
		{
			PrivateCustomer pCustomer = (PrivateCustomer)rental.getCustomer();
			name = pCustomer.getName();
		}
		else
		{
			BusinessCustomer bCustomer = (BusinessCustomer)rental.getCustomer();
			name = bCustomer.getCompanyName();
		}
		Console.print("-Udlejning-");
		if(!rental.isActivated()) { Console.print("--- AFLEVERET ---"); }
        Console.print("Maskine: "+rental.getMachine().getName());
		Console.print("Kunde: "+name);
        Console.print("Udlejningsdato (DD-MM-YYYY): "+Tools.makeNiceStringFromDate(rental.getRentalDate()));
		Console.print("Forventet afleveringsdato (DD-MM-YYYY): "+Tools.makeNiceStringFromDate(rental.getExpectedReturnDate()));
        if(!rental.isActivated()) { Console.print("Afleveringsdato (DD-MM-YYYY): "+rental.getReturnDate()); }
        Console.print("Depositum: "+rental.getDeposit()+"\tPris per dag: "+rental.getPricePerDay());
		if(!rental.isActivated()) { Console.print("Totalpris: "+rental.getTotalPrice()); }
	}
}